package lt.liepasoft.sudoku;

public class SudokuTable extends Grid {

	public final static int TABLE_SIZE = 9;	
	
	public SudokuTable() {
		super(TABLE_SIZE);		
	}
	
	public int[] getBox(int boxIndex){
		int[] box = new int[TABLE_SIZE];
        int x=0; int y=0;
        
        Point p = getBoxCoord(boxIndex);
        x=p.x; y=p.y;

        int i = 0;
        int t = 0;
        int j = 0;

        for (i=y; i<y+3; i++){
            for(j=x; j<x+3; j++){
            	box[t] = grid[getCellIndex(j,i)];
                t++;
            }
        }
		return box;
	}
	
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @return an int[] array with all possiblies values in that cell
	 * is possible to get a 0 length array. It means that a sudoku table is unsolvable
	 */
    public int[] possibleInputs(int x, int y){
    	//if in that cell already is a value
    	//then return null;
        if (grid[getCellIndex(x, y)] != 0)
            return null;

        boolean[] temp = new boolean[10];

        int[] row = getRow(getRowIndex(x,y));
        int[] col = getCol(getColIndex(x,y));        
        int[] box = getBox(getBoxIndex(x,y));

        for (int i=0; i<9; i++) {
            temp[row[i]] = true;
            temp[col[i]] = true;
            temp[box[i]] = true;
        }

        //suskaiciuojam kiek tusciu langeliu
        int empty = 0;
        for (int i=0; i<10; i++)
            if (!temp[i])
                empty++;

        int[] possiblies = new int[empty];

        //vel ieskom tusciu ir numeri irasom i possiblies
        empty = 0;
        for (int i=0; i<10; i++)
            if (!temp[i])
                possiblies[empty++] = i;
        
        return possiblies;
    }
	
	private int getBoxIndex(int x, int y){
        if ((x <= 2) && (y <= 2)) {
            return 0;
        }
        if ((x <= 2) && ((3 <= y) && (y <= 5))) {
        	return 3;
        }
        if ((x <= 2) && (y >= 6)) {
        	return 6;
        }
        if (((3 <= x) && (x <= 5)) && (y <= 2)) {
        	return 1;
        }
        if (((3 <= x) && (x <= 5)) && ((3 <= y) && (y <= 5))) {
        	return 4;
        }
        if (((3 <= x) && (x <= 5)) && (y >= 6)) {
        	return 7;
        }
        if ((x >= 6) && (y <= 2)) {
        	return 2;
        }
        if ((x >= 6) && ((3 <= y) && (y <= 5))) {
        	return 5;
        }
        if ((x >= 6) && (y >= 6)) {
        	return 8;
        }
        return -1;
	}

	public Point getBoxCoord(int boxIndex){
		int x=0,y=0;
        switch (boxIndex) {
	        case 0: {
	            x = 0; y = 0;
	        } break;
	        case 1: {
	            x = 3; y = 0;
	        } break;
	        case 2: {
	            x = 6; y = 0;
	        } break;
	        case 3: {
	            x = 0; y = 3;
	        } break;
	        case 4: {
	            x = 3; y = 3;
	        } break;
	        case 5: {
	            x = 6; y = 3;
	        } break;
	        case 6: {
	            x = 0; y = 6;
	        } break;
	        case 7: {
	            x = 3; y = 6;
	        } break;
	        case 8: {
	            x = 6; y = 6;
	        } break;
	    }
        return new Point(x,y);        
	}
}
